package org.itark.bbs.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.itark.bbs.common.config.RedisConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class RedisUtils {

    private static JedisPool pool = null;

    private static final ReentrantLock lock = new ReentrantLock();

    public static boolean set(String key, String value) {
        Jedis jedis = getResource();
        try {
            jedis.set(key, value);
        } catch (Exception e) {
            log.error("set failed:" + e);
        } finally {
            jedis.close();
        }
        return true;
    }

    public static boolean set(String key, String value, int second) {
        Jedis jedis = getResource();
        try {
            jedis.set(key, value);
            if (second > 0) {
                expire(key, second);
            }
        } catch (Exception e) {
            log.error("set failed:" + e);
            delete(key);
        } finally {
            jedis.close();
        }
        return true;
    }

    public static boolean expire(String key, int second) {
        Jedis jedis = getResource();
        try {
            jedis.expire(key, second);
        } catch (Exception e) {
            log.error("expire failed:" + e);
        } finally {
            jedis.close();
        }
        return true;
    }

    public static boolean delete(String key) {
        Jedis jedis = getResource();
        try {
            jedis.del(key);
        } catch (Exception e) {
            log.error("delete failed:" + e);
        } finally {
            jedis.close();
        }
        return true;
    }

    public static String get(String key) {
        Jedis jedis = getResource();
        try {
            return jedis.get(key);
        } catch (Exception e) {
            log.error("get failed, key:{}", key, e);
        } finally {
            jedis.close();
        }
        return null;
    }

    private static Jedis getResource() {
        if (null == pool) {
            lock.lock();
            try {
                initPool();
            } finally {
                lock.unlock();
            }
        }
        return pool.getResource();
    }

    private static void initPool() {
        if (null == pool) {
            RedisConfig config = SpringContextUtils.getBean(RedisConfig.class);
            pool = getPool(config.getHost(), config.getPort());
        }
    }

    private static JedisPool getPool(String ip, int port) {
        JedisPoolConfig config = new JedisPoolConfig();
        //控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
        //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
        config.setMaxTotal(100);
        //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
        config.setMaxIdle(5);
        //表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
        config.setMaxWaitMillis(1000 * 100);
        //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
        config.setTestOnBorrow(true);
        pool = new JedisPool(config, ip, port);
        return pool;
    }

}
